* specifying the id of the #GtkUIManager in the "constructor" attribute and the
* name of the object in the "id" attribute.
*
- * Objects must be given a name with the "id" attribute, which allows the
+ * Objects may be given a name with the "id" attribute, which allows the
* application to retrieve them from the builder with gtk_builder_get_object().
* An id is also necessary to use the object as property value in other parts of
- * the UI definition.
+ * the UI definition. GTK+ reserves ids starting and ending with ___ (3 underscores)
+ * for its own purposes.
* </para>
- * <note><para>
- * Prior to 2.20, GtkBuilder was setting the "name" property of constructed widgets to the
- * "id" attribute. In GTK+ 2.20 or newer, you have to use gtk_buildable_get_name() instead
- * of gtk_widget_get_name() to obtain the "id", or set the "name" property in your UI
- * definition.
- * </para></note>
* <para>
* Setting properties of objects is pretty straightforward with the
* <property> element: the "name" attribute specifies the name of the
}
object = element object {
- attribute id { xsd:ID },
+ attribute id { xsd:ID } ?,
attribute class { text },
attribute type-func { text } ?,
attribute constructor { text } ?,
</define>
<define name="object">
<element name="object">
- <attribute name="id">
- <data type="ID" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
- </attribute>
+ <optional>
+ <attribute name="id">
+ <data type="ID" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
+ </attribute>
+ </optional>
<attribute name="class">
<text/>
</attribute>
for (l = data->requested_objects; l; l = l->next)
{
- if (strcmp (l->data, object) == 0)
+ if (g_strcmp0 (l->data, object) == 0)
return TRUE;
}
return;
}
+ data->object_counter++;
+
if (!object_id)
{
- error_missing_attribute (data, element_name, "id", error);
- return;
+ object_id = g_strdup_printf ("___object_%d___", data->object_counter++);
}
++data->cur_object_level;
return;
}
-
g_hash_table_insert (data->object_ids, g_strdup (object_id), GINT_TO_POINTER (line));
}
gint requested_object_level;
gint cur_object_level;
+ gint object_counter;
+
GHashTable *object_ids;
} ParserData;
g_object_unref (image);
}
+static void
+test_no_ids (void)
+{
+ GtkBuilder *builder;
+ GError *error = NULL;
+ GObject *obj;
+ const gchar buffer[] =
+ "<interface>"
+ " <object class=\"GtkInfoBar\">"
+ " <child internal-child=\"content_area\">"
+ " <object class=\"GtkHBox\">"
+ " <child>"
+ " <object class=\"GtkLabel\">"
+ " <property name=\"label\" translatable=\"yes\">Message</property>"
+ " </object>"
+ " <packing>"
+ " <property name='expand'>False</property>"
+ " </packing>"
+ " </child>"
+ " </object>"
+ " </child>"
+ " <child internal-child=\"action_area\">"
+ " <object class=\"GtkVButtonBox\">"
+ " <child>"
+ " <object class=\"GtkButton\" id=\"button_ok\">"
+ " <property name=\"label\">gtk-ok</property>"
+ " <property name=\"use-stock\">yes</property>"
+ " </object>"
+ " </child>"
+ " </object>"
+ " </child>"
+ " <action-widgets>"
+ " <action-widget response=\"1\">button_ok</action-widget>"
+ " </action-widgets>"
+ " </object>"
+ "</interface>";
+
+ builder = gtk_builder_new ();
+ gtk_builder_add_from_string (builder, buffer, -1, &error);
+ g_assert (error == NULL);
+
+ obj = gtk_builder_get_object (builder, "button_ok");
+ g_assert (GTK_IS_BUTTON (obj));
+
+ g_object_unref (builder);
+}
+
int
main (int argc, char **argv)
{
g_test_add_func ("/Builder/GMenu", test_gmenu);
g_test_add_func ("/Builder/LevelBar", test_level_bar);
g_test_add_func ("/Builder/Expose Object", test_expose_object);
+ g_test_add_func ("/Builder/No IDs", test_no_ids);
return g_test_run();
}